package com.wxsong.authplatform.authweb.controller.menu;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wxsong.authplatform.authweb.controller.BaseController;
import com.wxsong.authplatform.authweb.controller.common.Const;
import com.wxsong.authplatform.authweb.controller.menu.dto.MenuDTO;
import com.wxsong.authplatform.authweb.exception.InstantException;
import com.wxsong.authplatform.authweb.model.menu.Menu;
import com.wxsong.authplatform.authweb.service.menu.MenuService;
import com.wxsong.authplatform.authweb.util.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/menu")
public class MenuController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(MenuController.class);

    @Resource
    private MenuService menuService;

    @RequestMapping(value = "/index")
    public String index(){
        return "menu/index";
    }

    @RequestMapping(value = "/add_index")
    public String toAdd(ModelMap modelMap, String id){
        modelMap.put("id", id);
        return "menu/add";
    }
    @RequestMapping(value = "/update_index")
    public String toUpdate(ModelMap modelMap, String ids){
        String id = Base64Util.decode(ids);
        Menu menu = menuService.getById(Long.parseLong(id));
        modelMap.put("menu", menu);
        modelMap.put("id", Base64Util.encode(menu.getId()+""));
        return "menu/update";
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public Response list(MenuDTO menuDTO){
        System.out.println(menuDTO);
        Map<String, Object> paramMap = Maps.newHashMap();
        List list = Lists.newArrayList();
        try {
            paramMap.put("name", menuDTO.getName());
            Long count = menuService.count(paramMap);
            if (count.compareTo(0l) > 0) {
                list = menuService.list(getFrom(menuDTO.getPage(), getSize(menuDTO.getRows())), getSize(menuDTO.getRows()), paramMap);
            }
            parseList(list);
            return ListResponse.success(count, list);
        }catch (Exception e){
            logger.error("/menu/list  error", e);
            return Response.fail(ResponseCode.FAIL.info);
        }

    }

    private void parseList(List<Menu> list) {
        List tmp = Lists.newArrayList();
        for (Menu menu : list){
            MenuDTO menuDTO = new MenuDTO();
            menuDTO.setId(Base64Util.encode(menu.getId()+""));
            menuDTO.setName(menu.getName());
            menuDTO.setUrl(menu.getUrl());
            menuDTO.setDescription(menu.getDescription());
            tmp.add(menuDTO);
        }
        list.clear();
        list.addAll(tmp);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Response add(MenuDTO menuDTO){
        Map resultMap = Maps.newHashMap();
        Menu menu = changeMenu(menuDTO);
        try {
            check(menu);
            int i = menuService.add(menu);
            if(i < 1){
                return Response.fail(ResponseCode.ADD_MENU_FAIL);
            }
        }catch (InstantException e){
            logger.error("/menu/add  error", e);
            return Response.fail(ResponseCode.ADD_MENU_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/menu/add  error", e);
            return Response.fail(ResponseCode.ADD_MENU_FAIL);
        }
        return Response.success(resultMap);
    }

    @RequestMapping(value = "/modify", method = RequestMethod.POST)
    @ResponseBody
    public Response modify(MenuDTO menuDTO){
        Map resultMap = Maps.newHashMap();
        try {
//            Long id = Long.parseLong(Base64Util.decode(menuDTO.getId()));
            Long id = Long.parseLong(menuDTO.getId());
            Menu menu = menuService.getById(id);
            if(null == menu){
                throw new InstantException("菜单不存在");
            }
            int c = menuService.updateInfo(id, menuDTO.getName(), menuDTO.getUrl(), menuDTO.getDescription());
            if (c < 0) {
                return Response.fail(ResponseCode.UPDATE_MENU_FAIL);
            }
        }catch (InstantException e){
            logger.error("/menu/modify  error", e);
            return Response.fail(ResponseCode.UPDATE_MENU_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/menu/modify  error", e);
            return Response.fail(ResponseCode.UPDATE_MENU_FAIL);
        }
        return Response.success(resultMap);
    }
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Response delete(String idStr){
        Map resultMap = Maps.newHashMap();
        try {
            Long[] ids = ids(idStr);
            int count = menuService.delete(ids);
            if (count < 0) {
                return Response.fail(ResponseCode.DELETE_MENU_FAIL);
            }
        }catch (InstantException e){
            logger.error("/menu/delete  error", e);
            return Response.fail(ResponseCode.DELETE_MENU_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/menu/delete  error", e);
            return Response.fail(ResponseCode.DELETE_MENU_FAIL.info);
        }
        return Response.success(resultMap);
    }

    @RequestMapping(value = "/queryMenu", method = RequestMethod.POST)
    @ResponseBody
    public List queryMenu(String id){
        Long menuNodeId = Const.MENU_ROOT_ID;
        if(!StringUtils.isBlank(id)){
            menuNodeId = Long.parseLong(id);
        }
        List<Menu> menuList = menuService.getByParentId(menuNodeId);
        List menus = changeMenu2MenuNode(menuList);
        return menus;
    }

    private List changeMenu2MenuNode(List<Menu> menuList) {
        List<MenuResponse.MenuNode> list = Lists.newArrayList();
        for (int i=0; i<menuList.size(); i++){
            Menu menu = menuList.get(i);
            MenuResponse.MenuNode menuNode = new MenuResponse.MenuNode();
            menuNode.setId(menu.getId());
            menuNode.setText(menu.getName());
            menuNode.setUrl(menu.getUrl());
            if(menu.getId() == Const.MENU_ROOT_ID){
                menuNode.setState(Const.MENU_NODE_OPEN);
            }
            Map attr = Maps.newHashMap();
            attr.put("description", menu.getDescription());
            attr.put("code", menu.getCode());
            menuNode.setAttributes(attr);
            list.add(menuNode);
        }
        return list;
    }

    private boolean check(Menu menu) throws InstantException{
        if(StringUtils.isBlank(menu.getName()) || StringUtils.isBlank(menu.getUrl())){
            throw new InstantException("参数不合法");
        }
        return true;
    }

    private Menu changeMenu(MenuDTO menuDTO) {
        String name = menuDTO.getName();
        String url = menuDTO.getUrl();
        String desc = menuDTO.getDescription();
        String code = menuDTO.getCode();
        long parentId = Long.parseLong(menuDTO.getParentId());
        Menu menu = new Menu(name, url, desc, parentId, code);
        return menu;
    }

}
